package com.yu.rpc.core.server;

import com.yu.rpc.core.model.RPCRequest;
import com.yu.rpc.core.model.RPCResponse;
import com.yu.rpc.core.registry.LocalRegistry;
import com.yu.rpc.core.serializer.JdkSerializer;
import com.yu.rpc.core.serializer.Serializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Method;

public class HttpServerHandler implements Handler<HttpServerRequest> {
    @Override
    public void handle(HttpServerRequest request) {
        System.out.println("receive request" + request.method() + " " + request.uri());
        Serializer serializer = new JdkSerializer();
        request.bodyHandler(body -> {
            RPCRequest rpcRequest = null;
            byte[] bytes = body.getBytes();
            try {
                rpcRequest = serializer.deserialize(bytes, RPCRequest.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            RPCResponse rpcResponse = new RPCResponse();
            if (rpcRequest == null) {
                rpcResponse.setMessage("request is null");
                doResponse(request, rpcResponse, serializer);
                return;
            }
            try {
                Class<?> classZ = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = classZ.getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
                Object result = method.invoke(classZ.newInstance(), rpcRequest.getParams());
                rpcResponse.setResult(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");
            } catch (Exception e) {
                e.printStackTrace();
            }
            doResponse(request, rpcResponse, serializer);
        });
    }

    private void doResponse(HttpServerRequest request, RPCResponse response, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type", "application/json; charset=utf-8");
        try {
            byte[] serialized = serializer.serialize(response);
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
